package com.jayqqaa12.service.system;

import com.jayqqaa12.jbase.jfinal.auto.BaseService;
import com.jayqqaa12.jbase.sdk.util.ShiroExt;
import com.jayqqaa12.model.Tree;
import com.jayqqaa12.model.TreeKit;
import com.jayqqaa12.model.ZTree;
import com.jayqqaa12.model.system.Res;
import com.jayqqaa12.model.system.RoleRes;
import com.jayqqaa12.shiro.ShiroCache;
import com.jayqqaa12.shiro.ShiroInterceptor;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;

import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;

/**
 * Generated by Jbase.
 */
public class ResService extends BaseService<Res> {
	public static final ResService service = (ResService)new ResService().setDao(Res.dao);


	public List<Res> list(Integer pid) {
		List<Res> counts = dao.find(sql("system_res.getChildSize"));
		List<Res> list = null;
		if (pid == null) list = dao.findAllByWhere("where pid is null ");
		else list = dao.findAllByWhere("where pid= ?", pid);

		list.forEach(r -> {
			Res c = counts.stream().filter(res ->res.getPid()==r.getId()  ).collect(Collectors.toList()).get(0);

			if (c != null) r.put("childSize", c.get("c"));
		});

		return list;
	}

	public List<String> getUrls() {
		return TreeKit.getAttr(dao, sql("system_res.getUrls"), "url");
	}

	public List<String> getAuthUrls() {
		return getUrls().stream().filter(url -> new ShiroExt().hasPermission(url)).collect(Collectors.toList());
	}


	public List<Res> getChild(Integer id, Integer type) {
		ShiroExt ext = new ShiroExt();
		List<Res> list = null;

		if (type == null) return dao.findAllByWhere("where pid =?", id);
		else if (id == null && type == Res.TYPE_MEUE)
			list = dao.findAllByWhere(" where  pid is null and type =? order by seq ", type);
		else if (id == null && type == Res.TYPE_PERMISSION) list = dao.findAllByWhere("where pid is null order by seq");
		else if (type == Res.TYPE_MEUE) list = dao.findAllByWhere(" where  pid =? and type =? order by seq ", id, type);
		else if (type == Res.TYPE_PERMISSION) list = dao.findAllByWhere(" where  pid =? order by seq  ", id);

		if (id == null) return list;
		else if (Res.TYPE_PERMISSION == type) return list;
		else {
			ListIterator<Res> itor = list.listIterator();
			while (itor.hasNext()) {
				Res r = itor.next();
				if (r.getStr("url") == null) continue;
				if (!ext.hasPermission(r.getStr("url"))) {
					itor.remove();
				}
			}
		}

		return list;
	}

	/***
	 * 批量授权 会先删除所有权限再授权
	 *
	 * @param roleId
	 * @param resIds
	 * @return
	 */
	public boolean batchGrant(Object roleId, String resIds) {

		boolean result = RoleRes.dao.deleteByWhere("where role_id=?", roleId);

		if (StrKit.notBlank(resIds)) result =  batchAdd(roleId, resIds);
		ShiroCache.clearAuthorizationInfoAll();

		return result;
	}

	public boolean grant(int roleId, String resIds) {
		boolean result = false;
		if (StrKit.notBlank(resIds)) result = batchAdd(roleId, resIds);
		ShiroCache.clearAuthorizationInfoAll();
		return result;
	}

	public boolean batchAdd(Object roleId, String resIds) {

		List<RoleRes> list = Arrays.asList(resIds.split(","))
				.stream().map(resId -> {
					return new RoleRes().setRoleId(roleId).setResId(resId);
				})
				.collect(Collectors.toList());

		Db.batchSave(list, list.size());
		return true;
	}
	/**
	 * 转化为 easyui Tree 对象
	 *
	 * @param type
	 * @return
	 */
	public List<Tree> getTree(Integer pid, int type, Integer passId) {

		return getChild(pid, type).stream()
				.filter(res -> !res.getId().equals(passId))
				.map(res -> {
					Tree tree = new Tree(res.getId(), res.getPid(), res.getName(), res.getIconCls(), res.getAttrs(), false);
					tree.children = getTree(res.getId(), type, passId);
					if (!tree.children.isEmpty()) tree.changeState();
					return tree;
				}).collect(Collectors.toList());
	}

	public List<ZTree> getZTree() {
		return super.findAll().stream().map(r -> {
			ZTree zt = new ZTree(r.getId(), r.getName(), r.getPid());
			if (zt.id == 0) zt.setDisCheck(true);
			return zt;
		}).collect(Collectors.toList());
	}

	public boolean delete(String id) {
		
		removeAuthorization();
		return TreeKit.deleteByIdAndPid(dao, id);
	}
	
	@Override
	public boolean save(Res res) {
		
		boolean result = false;

		if (res.getId() == null) {
			result = res.save();
			
			
		} else result = res.update();

		removeAuthorization();

		return result;
	}
	
	private void removeAuthorization() {
		ShiroCache.clearAuthorizationInfoAll();
		ShiroInterceptor.updateUrls();
	}
}
